<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    /* 
        首先promise有几个要点，
        第一个是状态，
        第二个是两个回调的列表，因为两个状态都可以注册多个回调，
        第三个就是promise本身的一个返回值
    */

    const PENDING = "pending";
    const RESOLVED = "resolved";
    const REJECTED = "rejected";


    function myPromise(fn) {
        let self = this;
        this.state = PENDING;
        this.value = null;
        this.resolveCallback = [];
        this.rejectCallback = [];

        function resolve(value) {
            if (value instanceof myPromise) {
                return value.then(resolve, reject);
            }
            setTimeout(() => {
                if (self.state == PENDING) {
                    self.state = RESOLVED;
                    self.value = value;
                    self.resolveCallback.forEach(callback => {
                        callback(value);
                    });
                }
            }, 0)
        }

        function reject(value) {
            setTimeout(() => {
                if (self.state == PENDING) {
                    self.state = REJECTED;
                    self.value = value;
                    self.rejectCallback.forEach(callback => {
                        callback(value);
                    });
                }
            })
        }

        try {
            fn(resolve, reject);
        } catch (error) {
            reject(error);
        }
    }

    myPromise.prototype.then = function (onResolved, onRejected) {
        // 用一个变量保存前一个promise的状态
        let self = this;
        return new myPromise((resolve, reject) => {
            function Resolved() {
                try {
                    onResolved = typeof onResolved === 'function' ? onResolved : (value) => { return value }
                    let result = onResolved(self.value);
                    return result instanceof myPromise ? result.then(resolve, reject) : resolve(result);
                } catch (error) {
                    reject(error);
                }
            }
            function Rejected() {
                try {
                    // 检测是否有接收onRejected函数，没有的话就继续往下传(保证REJECTED的状态不变)
                    onRejected = typeof onRejected === 'function' ? onRejected : (e) => { reject(e) }
                    let result = onRejected(self.value);
                    return result instanceof MyPromise ? result.then(resolve, reject) : resolve(result);
                } catch (error) {
                    reject(error);
                }
            }
            switch (self.state) {
                // 这一步就相当于把状态改变的权利交给了上一个promise的回调
                case PENDING:
                    self.resolveCallback.push(Resolved);
                    self.rejectCallback.push(Rejected);
                    break;
                case REJECTED:
                    Rejected();
                    break;
                case RESOLVED:
                    Resolved();
                    break;
            }
        })
    }

    new myPromise((resolve, reject) => {
        reject("haha")
    }).then((value) => {
        console.log(value);
    })

</script>

</html>